<?php

if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Dayrui Website Management System
 *
 * @since		version 2.7.0
 * @author		Dayrui <dayrui@gmail.com>
 * @license     http://www.dayrui.com/license
 * @copyright   Copyright (c) 2011 - 9999, Dayrui.Com, Inc.
 */
 
class Upgrade extends M_Controller {

    private $rid;
    private $version;

    /**
     * 构造函数
     */
    public function __construct() {
        parent::__construct();
        $this->version = DR_VERSION;
    }

    /**
     * 内核升级环境
     */
    public function index() {
		$this->template->assign(array(
			'url' => 'http://update.dayrui.com/index.php?fc='.DR_LICENSE_ID.'&id='.DR_VERSION_ID.'&site='.urlencode(SITE_URL).'&admin='.ADMIN_URL.SELF,
			'menu' => $this->get_menu(array(
				fc_lang('内核升级') => 'admin/upgrade/index'
			))
		));
		$this->template->display('online.html');
	}

    /**
     * 程序升级环境
     */
    public function branch() {

        if (!is_file(WEBPATH.'config/version_branch.php')) {
            $this->index();exit;
        }

        $branch = require WEBPATH.'config/version_branch.php';
		$this->template->assign(array(
			'url' => 'http://update.dayrui.com/index.php?c=branch&fc='.DR_LICENSE_ID.'&id='.$branch['V_ID'].'&eid='.$branch['V_VERSION_ID'].'&site='.urlencode(SITE_URL).'&admin='.ADMIN_URL.SELF,
			'menu' => $this->get_menu(array(
				fc_lang('内核升级') => 'admin/upgrade/index'
			))
		));
		$this->template->display('online.html');
	}
	
	/**
     * 检查下载程序
     */
    public function update() {

    	$rid = $this->rid = (int)$this->input->get('rid');
        $branch = (int)$this->input->get('branch');
        if ($branch) {
            $branch = require FCPATH.'config/version_branch.php';
            if ($rid) {
                if ($branch['V_VERSION_ID'] != $rid) {
                    $this->admin_msg('您的系统版本不满足重新升级的条件');
                }
            } else {

            }
        } else {
            if ($rid) {
                if (DR_VERSION_ID != $rid) {
                    $this->admin_msg('您的系统版本不满足重新升级的条件');
                }
            } else {
                if (DR_VERSION_ID != $this->input->get('id') - 1) {
                    $this->admin_msg('您的系统版本不满足升级条件');
                }
            }
        }

    	$data = dr_catcher_data(urldecode($this->input->get('fid')));
    	if (!$data) {
            $this->admin_msg('您的服务器不支持远程下载');
        } elseif ($data == -1) {
			$this->admin_msg('更新包数据不存在');
		} elseif ($data == -2) {
			$this->admin_msg('您无权限下载更新包');
		} elseif ($data == -3) {
			$this->admin_msg('您的账号认证失败，请检查密码是否正确');
		} elseif ($data == -4) {
			$this->admin_msg('服务端核心文件不完整(2)，请联系在线客服纠正');
		} elseif ($data == -5) {
			$this->admin_msg('服务端文件不完整(1)，请联系在线客服纠正');
		} elseif ($data == -6) {
			$this->admin_msg('您的账号尚未认证通过，请联系在线客服补全资料');
		}

    	$save = WEBPATH.'cache/down/update.zip';
    	$check = WEBPATH.'cache/down/update/';
		if (!@file_put_contents($save, $data)) {
            $this->admin_msg('目录/cache/down/没有写入权限');
        }

		// 解压缩文件
		$this->load->helper('file');
		$this->load->library('Pclzip');
		$this->pclzip->PclFile($save);
		if ($this->pclzip->extract(PCLZIP_OPT_PATH, $check, PCLZIP_OPT_REPLACE_NEWER) == 0) {
			@unlink($save);
			delete_files(WEBPATH.'cache/down/', TRUE);
			$this->admin_msg("Error : " . $this->pclzip->errorInfo(true));
		}

		// 检查版本文件
        if ($branch) {
            if (!is_file($check.'config/version_branch.php') || !filesize($check.'config/version_branch.php')) {
                delete_files(WEBPATH.'cache/down/', TRUE);
                $this->admin_msg('升级文件不完整，没有找到版本文件');
            }
        } else {
            if (!is_file($check.'config/version.php') || !filesize($check.'config/version.php')) {
                delete_files(WEBPATH.'cache/down/', TRUE);
                $this->admin_msg('升级文件不完整，没有找到版本文件');
            }
        }

    	// 覆盖至网站根目录
    	$this->pclzip->extract(PCLZIP_OPT_PATH, WEBPATH, PCLZIP_OPT_REPLACE_NEWER);

        // 逐一验证文件是否被覆盖
        $this->_check_file(WEBPATH.'cache/down/update/');

        // 删除更新包
    	$this->dcache->set('install', TRUE);
    	delete_files(WEBPATH.'cache/down/', TRUE);

    	// 运行SQL语句
    	if (is_file(FCPATH.'update.sql')) {
    		$sql = file_get_contents(FCPATH.'update.sql');
			$sql = str_replace('{dbprefix}', $this->db->dbprefix, $sql);
			$sql_data = explode(';SQL_FINECMS_EOL', trim(str_replace(array(PHP_EOL, chr(13), chr(10)), 'SQL_FINECMS_EOL', $sql)));
			foreach($sql_data as $query){
				if (!$query) continue;
				$queries = explode('SQL_FINECMS_EOL', trim($query));
				$ret = '';
				foreach($queries as $query) {
					$ret .= $query[0] == '#' || $query[0].$query[1] == '--' ? '' : $query; 
				}
				if (!$ret) continue;
				$this->db->query($ret);
			}
			@unlink(FCPATH.'update.sql');
    	}

        $this->system_log('升级版本'); // 记录日志
    	//检查update控制器
		if (is_file(FCPATH.'dayrui/controllers/admin/Update.php')) {
            $this->admin_msg('正在升级数据，请稍候...', dr_url('update/index'), 2);
        }
		
		$this->admin_msg('升级完成，请按F5刷新整个页面', dr_url('home/main'), 1);
    }

    // 遍历检测文件
    private function _check_file($source_dir, $directory_depth = 0) {

        if ($fp = @opendir($source_dir)) {
            $filedata	= array();
            $new_depth	= $directory_depth - 1;
            $source_dir	= rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
            while (FALSE !== ($file = readdir($fp))) {
                if ($file === '.'
                    || $file === '..'
                    || $file[0] === '.') {
                    continue;
                }
                is_dir($source_dir.$file) && $file .= DIRECTORY_SEPARATOR;

                if (($directory_depth < 1 || $new_depth > 0)
                    && is_dir($source_dir.$file)) {
                    $filedata[$file] = $this->_check_file($source_dir.$file, $new_depth);
                } else {
                    $file1 = $source_dir.$file; // 更新包文件
                    if (!is_file($file1)) {
                        $this->admin_msg($file1.'不存在');
                    }
                    $file2 = str_replace('cache/down/update/', '', $source_dir).$file; // 当前系统文件
                    if (is_file($file2)) {
                        $md1 = md5(file_get_contents($file1));
                        $md2 = md5(file_get_contents($file2));
                        if ($md1 != $md2) {
                            delete_files(WEBPATH.'cache/down/', TRUE);
                            delete_files(WEBPATH.'cache/backup/'.$this->version.'/', TRUE);
                            $this->admin_msg('文件/'.str_replace(FCPATH, '', $file2).'覆盖失败，<br>在线升级前请给全站可写权限，以便更新文件的写入<br>然后再点“重新升级”的链接升级程序');
                            exit;
                        }
                    }
                }
            }
            closedir($fp);
            return $filedata;
        }
    }

}